# -*- coding: utf-8 -*-
from PyQt5 import QtCore,QtGui,QtWidgets
from PyQt5.Qt import *
import sys
import time
import cv2
from recgnition import doRecognize
class Table(QWidget):
    def __init__(self):
        super(Table, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("联系人")
        self.setWindowIcon(QIcon("./img/logo.ico"))
        self.resize(400, 300)

        conLayout = QHBoxLayout()
        self.tableWidget = QTableWidget()
        self.tableWidget.setRowCount(20)
        self.tableWidget.setColumnCount(2)
        conLayout.addWidget(self.tableWidget)
        self.tableWidget.setHorizontalHeaderLabels(['姓名  ', '信息'])
        self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.read()
        self.setLayout(conLayout)
        self.tableWidget.itemChanged.connect(self.change)
    def read(self):
        fr = open("message.txt",'r+')
        dic = eval(fr.read())   #读取的str转换为字典
        i=0
        for key in dic:
            print(key + ":" + str(dic[key]))
            newItem = QTableWidgetItem(key)
            self.tableWidget.setItem(i, 0, newItem)
            newItem = QTableWidgetItem(dic[key])
            self.tableWidget.setItem(i, 1, newItem)
            i = i+1
        fr.close()
    def change(self):
        i = 0
        #print(self.tableWidget.selectedItems())
        dic = {}
        while(i<20):
            if self.tableWidget.item(i,0) is None:
                break
            if self.tableWidget.item(i,1) is None:
                break
            key = self.tableWidget.item(i,0).text()
            print(key)
            value = self.tableWidget.item(i,1).text()
            print(value)
            dic[key] = value
            i = i+1
        fw = open("message.txt",'w+')
        fw.write(str(dic))      #把字典转化为str
        fw.close()
        #self.read()
class LoadingMask(QMainWindow):
    def __init__(self, parent, gif=None, tip=None, min=0):
        """
        gif优先级高于 tip，两者同时赋值优先使用 gif
        :param parent:
        :param gif:
        :param tip:
        :param min:
        """
        super(LoadingMask, self).__init__(parent)

        self.min = min
        self.show_time = 0

        parent.installEventFilter(self)

        self.label = QLabel()

        if not tip is None:
            self.label.setText(tip)
            font = QFont('Microsoft YaHei', 10, QFont.Normal)
            font_metrics = QFontMetrics(font)
            self.label.setFont(font)
            self.label.setFixedSize(font_metrics.width(tip, len(tip))+10, font_metrics.height()+5)
            self.label.setAlignment(Qt.AlignCenter)
            self.label.setStyleSheet(
                'QLabel{background-color: rgba(0,0,0,70%);border-radius: 0px; color: white; padding: 0px;}')

        if not gif is None:
            self.movie = QMovie(gif)
            self.label.setMovie(self.movie)
            self.label.setAttribute(Qt.WA_TranslucentBackground)
            self.label.setFixedSize(QSize(400, 200))
            self.label.setScaledContents(True)
            self.movie.start()

        layout = QHBoxLayout()
        widget = QWidget()
        widget.setObjectName('background')
        widget.setAttribute(Qt.WA_TranslucentBackground)
        #widget.setStyleSheet('QWidget#background{background-color: rgba(255, 255, 255, 40%);}')
        widget.setLayout(layout)
        layout.addWidget(self.label)

        self.setCentralWidget(widget)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.Tool)
        self.hide()

    def eventFilter(self, widget, event):
        events = {QMoveEvent, QResizeEvent, QPaintEvent}
        if widget == self.parent():
            if type(event) == QCloseEvent:
                self.close()
                return True
            elif type(event) in events:
                self.moveWithParent()
                return True
        return super(LoadingMask, self).eventFilter(widget, event)

    def moveWithParent(self):
        if self.parent().isVisible():
            self.move(self.parent().geometry().x(), self.parent().geometry().y())
            self.setFixedSize(QSize(self.parent().geometry().width(), self.parent().geometry().height()))

    def show(self):
        super(LoadingMask, self).show()
        self.show_time = time.time()
        self.moveWithParent()

    def close(self):
        # 显示时间不够最小显示时间 设置Timer延时删除
        if (time.time() - self.show_time) * 1000 < self.min:
            QTimer().singleShot((time.time() - self.show_time)*1000+10, self.close)
        else:
            super(LoadingMask, self).hide()
            super(LoadingMask, self).deleteLater()

    @staticmethod
    def showToast(window, tip='加载中...', duration=500, appended_task=None):
        mask = LoadingMask(window, tip=tip)
        mask.show()

        def task():
            mask.deleteLater()
            if callable(appended_task):
                appended_task()
        # 一段时间后移除组件
        QTimer().singleShot(duration, task)

class Ui_MainWindow(QtWidgets.QWidget):
    def __init__(self,parent=None):
        super().__init__(parent) #父类的构造函数
        self.timer_camera = QtCore.QTimer() #定义定时器，用于控制显示视频的帧率
        self.cap = cv2.VideoCapture()       #视频流
        self.CAM_NUM = 0                    #为0时表示视频流来自笔记本内置摄像头
        self.setWindowTitle("大眼萌")
        self.setWindowIcon(QtGui.QIcon("./img/logo.ico"))
        self.set_ui()                       #初始化程序界面
        self.slot_init()                    #初始化槽函数

    '''程序界面布局'''
    def set_ui(self):
        pix = QPixmap('./img/camera.png')
        lb = QLabel(self)
        lb.setGeometry(250,20,500,500)
        lb.setPixmap(pix)
        #lb.setStyleSheet("border: 2px solid white")
        lb.setScaledContents(True)
        self.__layout_main = QtWidgets.QHBoxLayout()           #总布局
        self.__layout_fun_button = QtWidgets.QVBoxLayout()      #按键布局
        self.__layout_data_show = QtWidgets.QVBoxLayout()       #数据(视频)显示布局
        self.button_open_camera = QtWidgets.QPushButton('打开相机') #建立用于打开摄像头的按键
        self.button_register = QtWidgets.QPushButton('录入信息')           #建立用于退出程序的按键
        self.button_close = QtWidgets.QPushButton('退出')           #建立用于退出程序的按键
        self.button_output = QtWidgets.QPushButton('输出')           #建立用于输出程序的按键
        self.button_train = QtWidgets.QPushButton('训练')           #建立用于训练程序的按键
        self.button_open_camera.setMinimumHeight(50)                #设置按键大小
        self.button_register.setMinimumHeight(50)
        self.button_close.setMinimumHeight(50)
        self.button_train.setMinimumHeight(50)
        self.button_output.setMinimumHeight(50)

        self.button_close.move(10,100)                      #移动按键
        '''信息显示'''
        self.label_show_camera = QtWidgets.QLabel()   #定义显示视频的Label
        self.label_show_camera.setFixedSize(641,481)    #给显示视频的Label设置大小为641x481
        '''把按键加入到按键布局中'''
        self.__layout_fun_button.addWidget(self.button_open_camera) #把打开摄像头的按键放到按键布局中
        self.__layout_fun_button.addWidget(self.button_register)       #把录入程序的按键放到按键布局中
        self.__layout_fun_button.addWidget(self.button_output)       #把输出程序的按键放到按键布局中
        self.__layout_fun_button.addWidget(self.button_train)       #把模式训练的按键放到按键布局中
        self.__layout_fun_button.addWidget(self.button_close)       #把退出程序的按键放到按键布局中
        '''把某些控件加入到总布局中'''
        self.__layout_main.addLayout(self.__layout_fun_button)      #把按键布局加入到总布局中
        self.__layout_main.addWidget(self.label_show_camera)        #把用于显示视频的Label加入到总布局中
        '''总布局布置好后就可以把总布局作为参数传入下面函数'''
        self.setLayout(self.__layout_main) #到这步才会显示所有控件

    '''初始化所有槽函数'''
    def slot_init(self):
        self.button_open_camera.clicked.connect(self.button_open_camera_clicked)    #若该按键被点击，则调用button_open_camera_clicked()
        self.button_register.clicked.connect(self.button_register_clicked)    #若该按键被点击，则调用button_register_clicked()
        self.button_train.clicked.connect(self.button_train_clicked)    #若该按键被点击，则调用button_register_clicked()
        self.button_output.clicked.connect(self.button_output_clicked)    #若该按键被点击，则调用button_output_clicked()
        self.timer_camera.timeout.connect(self.show_camera) #若定时器结束，则调用show_camera()
        self.button_close.clicked.connect(self.close)#若该按键被点击，则调用close()，注意这个close是父类QtWidgets.QWidget自带的，会关闭程序


    '''槽函数之一'''
    def button_register_clicked(self):
        self.table = Table()
        example = self.table
        example.show()

    def button_train_clicked(self):
        self.child_window = Child()
        widget = self.child_window
        widget.setFixedSize(400, 200)
        #widget.setStyleSheet('QWidget{background-color:black;}')

        #widget.setWindowOpacity(0.93)  # 设置窗口透明度
        #widget.setAttribute(Qt.WA_TranslucentBackground)

        loading_mask = LoadingMask(widget, './img/loading1.gif')
        widget.show()
        widget.move(850,400)
        loading_mask.show()
        self.timer = QTimer(self)  # 初始化一个定时器
        self.timer.timeout.connect(self.child_window.close)  # 计时结束调用operate()方法
        self.timer.start(5000)  # 设置计时间隔并启动 2s后关闭窗口


    def button_open_camera_clicked(self):
        doRecognize()

    def show_camera(self):
        flag,self.image = self.cap.read()  #从视频流中读取

        show = cv2.resize(self.image,(640,480))     #把读到的帧的大小重新设置为 640x480
        show = cv2.cvtColor(show,cv2.COLOR_BGR2RGB) #视频色彩转换回RGB，这样才是现实的颜色
        showImage = QtGui.QImage(show.data,show.shape[1],show.shape[0],QtGui.QImage.Format_RGB888) #把读取到的视频数据变成QImage形式
        self.label_show_camera.setPixmap(QtGui.QPixmap.fromImage(showImage))  #往显示视频的Label里显示QImage

    def button_output_clicked(self):
        #
        QMessageBox.information(self,"提示","输出语音",QMessageBox.Yes)

class Child(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowFlags(Qt.FramelessWindowHint) # 设置为无标题栏
        self.setWindowOpacity(0.1)  # 设置窗口透明度
        self.setAttribute(Qt.WA_TranslucentBackground)
        ##self.setWindowTitle("我是子窗口啊")

if __name__ =='__main__':
    app = QtWidgets.QApplication(sys.argv)  #固定的，表示程序应用
    ui = Ui_MainWindow()                    #实例化Ui_MainWindow
    ui.show()                               #调用ui的show()以显示。同样show()是源于父类QtWidgets.QWidget的
    sys.exit(app.exec_())                   #不加这句，程序界面会一闪而过